﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Security.Cryptography;
using System.Drawing.Drawing2D;
using System.IO;

namespace MapEditorMario
{
    public partial class EditPicture : Form
    {

        String fileName;
        Bitmap imageBitmap;
        int countCellHeight;
        int countCellWidth;
        List<Bitmap> listBmp = new List<Bitmap>();
        List<Bitmap> listBmpTemp = new List<Bitmap>();

        PictureBox pic = new PictureBox();
        int[] matrix;// = new int[listBmp.Count];

        //Quadtree
        QuadTree quadTreeBg;

        public EditPicture()
        {
            InitializeComponent();
            fileName = "";
            imageBitmap = null;
            countCellHeight = 0;
            countCellWidth = 0;

            //quadTreeBg = null;
        }

        private enum CompareResult
        {
            CompareOK,
            PixelNoMatch,
            SizeNoMatch
        }

        private static CompareResult Compare(Bitmap bmp1, Bitmap bmp2)
        {
            CompareResult result = CompareResult.CompareOK;
            //Test 2 Bitmap match of size
            if (bmp1.Size != bmp1.Size)
            {
                result = CompareResult.SizeNoMatch;
            }
            else
            {
                //Convert each Image to Byte array
                ImageConverter ic = new ImageConverter();
                byte[] image1 = new byte[1];
                image1 = (byte[])ic.ConvertTo(bmp1, image1.GetType());
                byte[] image2 = new byte[1];
                image2 = (byte[])ic.ConvertTo(bmp2, image2.GetType());

                //Compute a hash for each image
                SHA256Managed sha = new SHA256Managed();
                byte[] hash1 = sha.ComputeHash(image1);
                byte[] hash2 = sha.ComputeHash(image2);

                //Compare Hash value
                for (int i = 0; i < hash1.Length && i < hash2.Length
                                  && result == CompareResult.CompareOK; i++)
                {
                    if (hash1[i] != hash2[i])
                        result = CompareResult.PixelNoMatch;
                }
            }
            return result;
        }

        private Bitmap cutPic(Bitmap bitmap, int row, int col)
        {
            Rectangle rect = new Rectangle(row * 32, col * 32, 32, 32);
            Bitmap bmp = bitmap.Clone(rect,PixelFormat.DontCare);
            return bmp;
        }

        private void bt_loadPic_Click(object sender, EventArgs e)
        {
            proBar_loadPic.Value = 0;
            listBmp.Clear();
            oFDialog_loadPic.FileName = "";
            oFDialog_loadPic.Title = "Images";
            oFDialog_loadPic.Filter = "All Images|*.jpg; *bmp; *.png";
            oFDialog_loadPic.InitialDirectory = Application.StartupPath + @"\ImageTitle";
            DialogResult result = oFDialog_loadPic.ShowDialog();

            if (result != DialogResult.OK)
            {
                return;
            }

            if (oFDialog_loadPic.FileName.ToString() != "")
            {
                fileName = oFDialog_loadPic.FileName.ToString();
            }

            imageBitmap = new Bitmap(fileName);
            countCellWidth = imageBitmap.Width / 32;
            countCellHeight = imageBitmap.Height / 32;
            proBar_loadPic.Maximum = countCellWidth * countCellHeight;
            for (int i = 0; i < countCellHeight; i++)
            {
                for (int j = 0; j < countCellWidth; j++)
                {
                    Bitmap bm = cutPic(imageBitmap, j, i);
                    listBmp.Add(bm);
                    proBar_loadPic.Value++;
                }
            }
            MessageBox.Show("Load image success: " + listBmp.Count, "Information", MessageBoxButtons.OK);
            bt_compare.Enabled = true;
        }

        private void bt_compare_Click(object sender, EventArgs e)
        {
            //luu ma tran
            //int[,] matrix = new int[countCellWidth, countCellHeight];
            proBar_compare.Value = 0;
            matrix = new int[listBmp.Count];
            int index = 0;

            bool flag = false;
            proBar_compare.Maximum = 256;


            listBmpTemp.Clear();
            for (int i = 0; i < listBmp.Count; i++)
            {
                matrix[i] = index;

                flag = false;
                //so sanh voi list da luu tam picture
                for (int j = 0; j < listBmpTemp.Count; j++)
                {
                    if (Compare(listBmp[i], listBmpTemp[j]) == CompareResult.CompareOK)
                    //if (ComparePic(listBmp[i], listTemp[j]) == true)
                    {
                        flag = true; //da co

                        matrix[i] = j;
                        break;
                        //index--;

                    }
                }

                if (flag == false)
                {
                    listBmpTemp.Add(listBmp[i]);
                    proBar_compare.Value++;
                    if(proBar_compare.Value > 254){
                        proBar_compare.Value = 256;
                    }
                    index++;
                }
                
            }
            proBar_compare.Value = 256;
            MessageBox.Show("There are " + listBmpTemp.Count + " tiles diference","Information", MessageBoxButtons.OK);
            bt_saveTiles.Enabled = true;
        }

        private void SaveMatrix(String file_name, int[] matrix)
        {
            FileStream fs = new FileStream(file_name, FileMode.Create); //tao file moi
            StreamWriter sWriter = new StreamWriter(fs); //

            sWriter.Write(countCellWidth + " " + countCellHeight + "\n");

            int countWidth = 0;
            for (int i = 0; i < matrix.Length; i++)
            {
                sWriter.Write(matrix[i]);
                countWidth++;
                if (countWidth == countCellWidth)
                {
                    sWriter.Write("\n");
                    countWidth = 0;
                }
                else
                    sWriter.Write(" ");
            }

            sWriter.Flush();
            fs.Close();
        }

        private void SaveTilesObject(String file_name, int[] matrix)
        {
            FileStream fs = new FileStream(file_name, FileMode.Create); //tao file moi
            StreamWriter sWriter = new StreamWriter(fs); //

            sWriter.Write(6 + " " + countCellWidth * countCellHeight + " " + countCellWidth*32 + "\n");

            int countWidth = 0;
            int countHeight = 0;
            for (int i = 0; i < matrix.Length; i++)
            {
                sWriter.Write((i+1) + " ");
                sWriter.Write(matrix[i]);
                int pos_x = countWidth * 32;
                int pos_y = countHeight * 32;
                sWriter.Write(" "+pos_x);
                sWriter.Write(" "+pos_y);
                sWriter.Write(" "+(pos_x + 32));
                sWriter.Write(" "+(pos_y + 32));                
                sWriter.Write("\n");

                countWidth++;
                if (countWidth == countCellWidth)
                {
                    //sWriter.Write("\n");
                    countWidth = 0;
                    countHeight++;
                }
                
            }

            sWriter.Flush();
            fs.Close();
        }

        private void bt_saveTiles_Click(object sender, EventArgs e)
        {
            int sizeImg = listBmpTemp.Count * 32;
            Bitmap bmSave = new Bitmap(sizeImg, 32);

            //Save quadtree
            int size = (countCellWidth > countCellHeight) ? countCellWidth * 32 : countCellHeight * 32;
            quadTreeBg = new QuadTree(0, 0, size, 5);

            using (var canvas = Graphics.FromImage(bmSave))
            {
                canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                for (int i = 0; i < listBmpTemp.Count; i++)
                {
                    canvas.DrawImage(listBmpTemp[i], new Rectangle(i * 32, 0, 32, 32), 
                        new Rectangle(0, 0, listBmpTemp[i].Width, listBmpTemp[i].Height), GraphicsUnit.Pixel);
                }
                canvas.Save();
            }
            try
            {
                if (txt_saveTiles.Text == "")
                {
                    MessageBox.Show("Please enter name file", "Information", MessageBoxButtons.OK);
                    return;
                }
                bmSave.Save("MapEditor/" + txt_saveTiles.Text.Trim() + "-tiles.png", ImageFormat.Png);
                SaveMatrix("MapEditor/" + txt_saveTiles.Text.Trim() + "-tiles.txt", matrix);
                //imageBitmap.Save("ImageTitle/" + txt_saveTiles.Text.Trim() + ".png", ImageFormat.Png);
                SaveTilesObject("MapEditor/" + txt_saveTiles.Text.Trim() + "-tiles-obj.txt", matrix);
                
               //save nhu dang nay ne, cai nay moi save tiles
            }
            catch (Exception ex)
            {
                MessageBox.Show("Có lỗi khi cắt tiles.", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            //Save quadtree tiles bg, them doan code nay nua de luu vo quadtree
            //do luc tao lay len la ten cua no bao gom cao tiles roi,uh
            quadTreeBg.addAllTiles(Application.StartupPath + @"\MapEditor\" + txt_saveTiles.Text.Trim() + "-tiles.txt");
            quadTreeBg.divide();
            quadTreeBg.saveQTree("MapEditor/" + txt_saveTiles.Text.Trim() + "-tiles-obj-qt.txt");
            MessageBox.Show("Save Tiles map thành công.", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        

    }
}
